/**
 * @File name : DateOperator.java
 * @Description : 
 * @Creator : haifeng17
 * @CreateTime : Jun 1, 2016 3:30:59 PM
 * @Version : 1.0
 * @Update records:
 *      1.1 Jun 1, 2016 by haifeng17: 
 *      1.0 Jun 1, 2016 by haifeng17: Created 
 * All rights served : SINA Corporation
 */
package com.ent.app.bms.util;


import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 日期处理工具类
 * @author Lee
 */

public class DateOperator {
    //~ Static fields/initializers =============================================
    
    
    private static Log log = LogFactory.getLog(DateOperator.class);
    private static String defaultDatePattern = null;
    private static String timePattern = "HH:mm";
    public static final String TS_FORMAT = DateOperator.getDatePattern() + " HH:mm:ss.S";
    private static Calendar cale = Calendar.getInstance();
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm:ss");
    private static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //~ Methods ================================================================

    public DateOperator(){
    }
    
    /**
     * 获得服务器当前日期及时间，以格式为：yyyy-MM-dd HH:mm:ss的日期字符串形式返回
     */
    public static String getDateTime(){
        try{
            return sdf2.format(cale.getTime());
        } catch(Exception e){
            log.debug("DateOperator.getDateTime():" + e.getMessage());
            return "";
        }
    }
    /**
     * 获得服务器当前日期，以格式为：yyyy-MM-dd的日期字符串形式返回
     */
    public static String getDate(){
        try{
            return sdf.format(cale.getTime());
        } catch(Exception e){
            log.debug("DateOperator.getDate():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器当前时间，以格式为：HH:mm:ss的日期字符串形式返回
     */
    public static String getTime(){
        String temp = "";
        try{
            temp += sdf1.format(cale.getTime());
            return temp;
        } catch(Exception e){
            log.debug("DateOperator.getTime():" + e.getMessage());
            return "";
        }
    }


    /**
     * 统计时开始日期的默认值,
     * 今年的开始时间
     */
    public static String getStartDate(){
        try{
            return getYear() + "-01-01";
        } catch(Exception e){
            log.debug("DateOperator.getStartDate():" + e.getMessage());
            return "";
        }
    }

    /**
     * 统计时结束日期的默认值
     */
    public static String getEndDate(){
        try{
            return getDate();
        } catch(Exception e){
            log.debug("DateOperator.getEndDate():" + e.getMessage());
            return "";
        }
    }


    /**
     * 获得服务器当前日期的年份
     */
    public static String getYear(){
        try{
            //返回的int型，需要字符串转换
            return String.valueOf(cale.get(Calendar.YEAR));
        } catch(Exception e){
            log.debug("DateOperator.getYear():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器当前日期的月份
     */
    public static String getMonth(){
        try{
            //一个数字格式，非常好
            java.text.DecimalFormat df = new java.text.DecimalFormat();
            df.applyPattern("00");
            return df.format((cale.get(Calendar.MONTH) + 1));
            //return String.valueOf(cale.get(Calendar.MONTH) + 1);
        } catch(Exception e){
            log.debug("DateOperator.getMonth():" + e.getMessage());
            return "";
        }
    }

    public static class DateR {
        public static java.util.Date getDate(int year, int month, int day) {
            Calendar cal = Calendar.getInstance();
            cal.set(year, month - 1, day, 0, 0, 0);
            cal.set(Calendar.MILLISECOND, 0);
            return cal.getTime();
        }

        public static java.util.Date getDate(String year, String month, String day) {
            return getDate(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
        }

        public static Date getDate (String month, String day) {
            return getDate(getYear(), month, day);
        }

        public static void main(String[] args) {
            System.out.println(getDate("07", "11"));
        }
    }

    /**
     * 获得服务器在当前月中天数
     */
    public static String getDay(){
        try{
            return String.valueOf(cale.get(Calendar.DAY_OF_MONTH));
        } catch(Exception e){
            log.debug("DateOperator.getDay():" + e.getMessage());
            return "";
        }
    }

    /**
     * 比较两个日期相差的天数,
     * 第一个日期要比第二个日期要晚
     */
    public static int getMargin(String date1,String date2){
        int margin;
        try{
            ParsePosition pos = new ParsePosition(0);
            ParsePosition pos1 = new ParsePosition(0);
            Date dt1 = sdf.parse(date1,pos);
            Date dt2 = sdf.parse(date2,pos1);
            long l = dt1.getTime() - dt2.getTime();
            margin = (int)(l / (24 * 60 * 60 * 1000));
            return margin;
        } catch(Exception e){
            log.debug("DateOperator.getMargin():" + e.toString());
            return 0;
        }
    }


    /**
     * 比较两个日期相差的天数，格式不一样
     * 第一个日期要比第二个日期要晚
     */
    public static double getDoubleMargin(String date1,String date2){
        double margin;
        try{
            ParsePosition pos = new ParsePosition(0);
            ParsePosition pos1 = new ParsePosition(0);
            Date dt1 = sdf2.parse(date1,pos);
            Date dt2 = sdf2.parse(date2,pos1);
            long l = dt1.getTime() - dt2.getTime();
            margin = (l / (24 * 60 * 60 * 1000.00));
            return margin;
        } catch(Exception e){
            log.debug("DateOperator.getMargin():" + e.toString());
            return 0;
        }
    }


    /**
     * 比较两个日期相差的月数
     */
    public static int getMonthMargin(String date1,String date2){
        int margin;
        try{
            margin  = (Integer.parseInt(date2.substring(0,4)) - Integer.parseInt(date1.substring(0,4)))* 12;
            margin += (Integer.parseInt(date2.substring(4,7).replaceAll("-0","-")) - Integer.parseInt(date1.substring(4,7).replaceAll("-0","-")));
            return margin;
        } catch(Exception e){
            log.debug("DateOperator.getMargin():" + e.toString());
            return 0;
        }
    }

    /**
     * 返回日期加X天后的日期
     */
    public static String addDay(String date,int i){
        try{
            GregorianCalendar gCal = new GregorianCalendar(Integer.parseInt(date.substring(0,4)),Integer.parseInt(date.substring(5,7))-1,Integer.parseInt(date.substring(8,10)));
            gCal.add(GregorianCalendar.DATE,i);
            return sdf.format(gCal.getTime());
        } catch(Exception e){
            log.debug("DateOperator.addDay():" + e.toString());
            return getDate();
        }
    }

    /**
     * 返回日期加X月后的日期
     */
    public static String addMonth(String date,int i){
        try{
            GregorianCalendar gCal = new GregorianCalendar(Integer.parseInt(date.substring(0,4)),Integer.parseInt(date.substring(5,7))-1,Integer.parseInt(date.substring(8,10)));
            gCal.add(GregorianCalendar.MONTH,i);
            return sdf.format(gCal.getTime());
        } catch(Exception e){
            log.debug("DateOperator.addMonth():" + e.toString());
            return getDate();
        }
    }

    /**
     * 返回日期加X年后的日期
     */
    public static String addYear(String date,int i){
        try{
            GregorianCalendar gCal = new GregorianCalendar(Integer.parseInt(date.substring(0,4)),Integer.parseInt(date.substring(5,7))-1,Integer.parseInt(date.substring(8,10)));
            gCal.add(GregorianCalendar.YEAR,i);
            return sdf.format(gCal.getTime());
        } catch(Exception e){
            log.debug("DateOperator.addYear():" + e.toString());
            return "";
        }
    }


    /**
     * 返回某年某月中的最大天
     */
    public static int getMaxDay(String year,String month){
        int day = 0;
        try{
            int iyear = Integer.parseInt(year);
            int imonth = Integer.parseInt(month);
            if(imonth == 1 || imonth == 3 || imonth == 5 || imonth == 7 || imonth == 8 || imonth == 10 || imonth == 12){
                day = 31;
            } else if(imonth == 4 || imonth == 6 || imonth == 9 || imonth == 11){
                day = 30;
            } else if((0 == (iyear % 4)) && (0 != (iyear % 100)) || (0 == (iyear % 400))){
                day = 29;
            } else{
                day = 28;
            }
            return day;
        } catch(Exception e){
            log.debug("DateOperator.getMonthDay():" + e.toString());
            return 1;
        }
    }
    


    /**
     * 格式化日期
     */
    @SuppressWarnings("static-access")
    public String rollDate(String orgDate,int Type,int Span){
        try{
            String temp = "";
            int iyear,imonth,iday;
            int iPos = 0;
            char seperater = '-';
            if(orgDate == null || orgDate.length() < 6){
                return "";
            }

            iPos = orgDate.indexOf(seperater);
            if(iPos > 0){
                iyear = Integer.parseInt(orgDate.substring(0,iPos));
                temp = orgDate.substring(iPos + 1);
            } else{
                iyear = Integer.parseInt(orgDate.substring(0,4));
                temp = orgDate.substring(4);
            }

            iPos = temp.indexOf(seperater);
            if(iPos > 0){
                imonth = Integer.parseInt(temp.substring(0,iPos));
                temp = temp.substring(iPos + 1);
            } else{
                imonth = Integer.parseInt(temp.substring(0,2));
                temp = temp.substring(2);
            }

            imonth--;
            if(imonth < 0 || imonth > 11){
                imonth = 0;
            }

            iday = Integer.parseInt(temp);
            if(iday < 1 || iday > 31)
                iday = 1;

            Calendar orgcale = Calendar.getInstance();
            orgcale.set(iyear,imonth,iday);
            temp = this.rollDate(orgcale,Type,Span);
            return temp;
        }catch(Exception e){
            return "";
        }
    }

    public static String rollDate(Calendar cal,int Type,int Span){
        try{
            String temp = "";
            Calendar rolcale;
            rolcale = cal;
            rolcale.add(Type,Span);
            temp = sdf.format(rolcale.getTime());
            return temp;
        }catch(Exception e){
            return "";
        }
    }

    /**
     * 
     * 返回默认的日期格式
     * 
     */
    public static synchronized String getDatePattern() {
        defaultDatePattern = "yyyy-MM-dd";
        return defaultDatePattern;
    }

    /**
     * 将指定日期按默认格式进行格式代化成字符串后输出如：yyyy-MM-dd
     */
    public static final String getDate(Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate != null) {
            df = new SimpleDateFormat(getDatePattern());
            returnValue = df.format(aDate);
        }

        return (returnValue);
    }



    /**
     * 取得给定日期的时间字符串，格式为当前默认时间格式
     */
    public static String getTimeNow(Date theTime) {
        return getDateTime(timePattern, theTime);
    }

    /**
     * 取得当前时间的Calendar日历对象
     */
    public Calendar getToday() throws ParseException {
        Date today = new Date();
        SimpleDateFormat df = new SimpleDateFormat(getDatePattern());
        String todayAsString = df.format(today);
        Calendar cal = new GregorianCalendar();
        cal.setTime(convertStringToDate(todayAsString));
        return cal;
    }

    /**
     * 将日期类转换成指定格式的字符串形式
     */
    public static final String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate == null) {
            log.error("aDate is null!");
        } else {
            df = new SimpleDateFormat(aMask);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }
    
    /**
     * 将指定的日期转换成默认格式的字符串形式
     */
    public static final String convertDateToString(Date aDate) {
        return getDateTime(getDatePattern(), aDate);
    }

    
    /**
     * 将日期字符串按指定格式转换成日期类型
     * @param aMask 指定的日期格式，如:yyyy-MM-dd 
     * @param strDate 待转换的日期字符串
     */
    
    public static final Date convertStringToDate(String aMask, String strDate)
      throws ParseException {
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat(aMask);

        if (log.isDebugEnabled()) {
            log.debug("converting '" + strDate + "' to date with mask '"
                      + aMask + "'");
        }
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            log.error("ParseException: " + pe);
            throw pe;
        }
        return (date);
    }
    
    /**
     * 将日期字符串按默认格式转换成日期类型
     */
    public static Date convertStringToDate(String strDate)
      throws ParseException {
        Date aDate = null;

        try {
            if (log.isDebugEnabled()) {
                log.debug("converting date with pattern: " + getDatePattern());
            }
            aDate = convertStringToDate(getDatePattern(), strDate);
        } catch (ParseException pe) {
            log.error("Could not convert '" + strDate
                      + "' to a date, throwing exception");
            throw new ParseException(pe.getMessage(),
                                     pe.getErrorOffset());
                    
        }

        return aDate;
    }
    
    /**
     * 返回一个JAVA简单类型的日期字符串
     */
    public static String getSimpleDateFormat(){
        SimpleDateFormat formatter=new SimpleDateFormat();
        String NDateTime=formatter.format(new Date());
        return NDateTime;
    }
    
    /**
     * 将两个字符串格式的日期进行比较
     * @param last 要比较的第一个日期字符串
     * @param now   要比较的第二个日期格式字符串
     * @return true(last 在now 日期之前),false(last 在now 日期之后)
     */
    public static boolean compareTo(String last, String now) {
        try {
            SimpleDateFormat formatter = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            Date temp1 = formatter.parse(last);
            Date temp2 = formatter.parse(now);
            if (temp1.after(temp2))
                return false;
            else if (temp1.before(temp2))
                return true;
        } catch (ParseException e) {
            log.debug(e.getMessage());
        }
        return false;
    }    
    
    protected Object convertToDate(Class type, Object value) {
        DateFormat df = new SimpleDateFormat(TS_FORMAT);
        if (value instanceof String) {
            try {
                if (StringUtils.isEmpty(value.toString())) {
                    return null;
                }
                return df.parse((String) value);
            } catch (Exception pe) {
                throw new ConversionException("Error converting String to Timestamp");
            }
        }

        throw new ConversionException("Could not convert "
                + value.getClass().getName() + " to " + type.getName());
    }




    
    /**
     *  为查询日期添加最小时间
     *  @param 目标类型Date
     *  @param 转换参数Date
     *  @return 
     */   
    @SuppressWarnings("deprecation")
    public static Date addStartTime(Date param) {
        Date date = param;
        try{
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            return date;
        }catch(Exception ex){
            return date;
        }
    }


    
    /**
     * 为查询日期添加最大时间
     *  @param 目标类型Date
     *  @param 转换参数Date
     *  @return 
     */   
    @SuppressWarnings("deprecation")
    public static Date addEndTime(Date param) {
        Date date = param;
        try{
            date.setHours(23);
            date.setMinutes(59);
            date.setSeconds(0);
            return date;
        }catch(Exception ex){
            return date;
        }
    }
    

    
    /**
     * 返回系统现在年份中指定月份的天数
     * @param 月份month
     * @return 指定月的总天数
     */
    @SuppressWarnings("deprecation")
    public static String getMonthLastDay(int month)
    {
        Date date=new Date();
        int[][] day={{0,30,28,31,30,31,30,31,31,30,31,30,31},
                        {0,31,29,31,30,31,30,31,31,30,31,30,31}};   
        int year=date.getYear()+1900;
        if(year%4==0 && year%100!=0 || year%400==0) 
        {
            return day[1][month]+"";
        }
        else
        {
            return day[0][month]+"";
        }
    }
    
    /**
     * 返回指定年份中指定月份的天数
     * @param 年份year
     * @param 月份month
     * @return 指定月的总天数
     */
    public static String getMonthLastDay(int year,int month)
    {
        int[][] day={{0,30,28,31,30,31,30,31,31,30,31,30,31},
                        {0,31,29,31,30,31,30,31,31,30,31,30,31}};
        if(year%4==0 && year%100!=0 || year%400==0) 
        {
            return day[1][month]+"";
        }
        else
        {
            return day[0][month]+"";
        }
    }
    
    /**
     * 取得当前时间的日戳
     * @return
     */
    @SuppressWarnings("deprecation")
    public static String getTimestamp(){
        Date date=new Date();
        String timestamp=""+(date.getYear()+1900)+date.getMonth()+date.getDate()+date.getMinutes()+date.getSeconds()+date.getTime();
        return timestamp;
    }
    /**
     * 取得指定时间的日戳
     * @return
     */
    @SuppressWarnings("deprecation")
    public static String getTimestamp(Date date){
        String timestamp=""+(date.getYear()+1900)+date.getMonth()+date.getDate()+date.getMinutes()+date.getSeconds()+date.getTime();
        return timestamp;
    }
    
    /**
     * 
     * @throws ParseException 
     * @Description : Get date range by a day
     * if parameters are (new Date(), -3, -1, "23:30:00", "00:30:00") then the result should be : [2016-05-29 23:30:00,2016-05-31 00:30:00]
     * Such as withdraw operation, program will statistic the required date range
     * @Param : (new Date(), -3, -1, "23:30:00", "00:30:00")
     * @Return : Map<String, Date>, the detailed result should be: ["startTime", 2016-05-29 23:30:00, "endTime", 2016-05-31 00:30:00]
     * @CreateTime : Jun 1, 2016 4:20:03 PM
     * @Updator : 
     * @UpdateTime :
     */
    public static Map<String, Date> getDateRange(String day, int startDuration, int endDuration, String startHms, String endHms) throws ParseException {
        Map<String, Date> dateRange = new HashMap<String, Date>();
        String startDateStr = DateOperator.addDay(day, startDuration);
        String endDateStr = DateOperator.addDay(day, endDuration);
        String startTimeStr = startDateStr + " " + startHms;
        String endTimeStr = endDateStr + " " + endHms;
        Date startTime = DateOperator.convertStringToDate("yyyy-MM-dd HH:mm:ss", startTimeStr);
        Date endTime = DateOperator.convertStringToDate("yyyy-MM-dd HH:mm:ss", endTimeStr);
        dateRange.put("startTime", startTime);
        dateRange.put("endTime", endTime);
        return dateRange;
    }
    
    public static void main(String[] args) throws ParseException{
        System.out.println(DateOperator.getDate());//获取日期格式为2010-08-12
        System.out.println(DateOperator.getDateTime());//获取日期格式为2010-08-12 18:08:21
        System.out.println(DateOperator.getTime());//获取日期格式为18:08:21
        System.out.println(DateOperator.getYear());//获取当前时间年份2010
        System.out.println(DateOperator.getMonth());//获取当年时间月份08
        System.out.println(DateOperator.getStartDate());//获取2010-01-01
        System.out.println(DateOperator.getEndDate());//2010-08-12
        System.out.println(DateOperator.getDay());//获得服务器在当前月中已经过了的天数12
        System.out.println(DateOperator.getMargin("2010-05-02", "2010-04-01"));//比较两个日期相差的天数
        System.out.println(DateOperator.getDoubleMargin("2010-05-07 23:22:11", "2010-04-01 01:33:33"));
        
        long current=System.currentTimeMillis();//当前时间毫秒数
        long zero=current/(1000*3600*24)*(1000*3600*24)-TimeZone.getDefault().getRawOffset();//今天零点零分零秒的毫秒数
        long twelve=zero+24*60*60*1000-1;//今天23点59分59秒的毫秒数
        long yesterday=System.currentTimeMillis()-24*60*60*1000;//昨天的这一时间的毫秒数
        System.out.println(new Timestamp(current));//当前时间
        System.out.println(new Timestamp(yesterday));//昨天这一时间点
        System.out.println(new Timestamp(zero));//今天零点零分零秒
        System.out.println(new Timestamp(twelve));//今天23点59分59秒
        
        Map<String, Date> dateRange = new HashMap<String, Date>();
        dateRange = DateOperator.getDateRange(DateOperator.getDate(), -2, -2, "23:30:00.0", "00:30:00.999");
        System.out.println(dateRange.get("startTime") + "|" + dateRange.get("endTime"));
        /*
        String today = DateOperator.getDate();
        String startDate = DateOperator.addDay(today, -3);
        String endDate = DateOperator.addDay(today, -1);
        String startTime = startDate + " 23:30:00";
        String endTime = endDate + " 00:30:00";
      //System.out.println(startDate+" | "+endDate);
//        Date startTime = DateOperator.convertStringToDate(DateOperator.addDay(today, -3));
//        Date endTime = DateOperator.convertStringToDate(DateOperator.addDay(today, -1));
        System.out.println(startTime+"|"+endTime);*/
        
    }
}

